import { createClient } from 'redis';
import config from './configuration.js';
import log from './logger.js';
import mysqlHelper from './mysqlHelper.js';

const clientMap = new Map();

/**
 *
 * @param {*} db_index
 * @returns {Promise<import('redis').RedisClientType>}
 */
async function getClient(db_index = 0) {
    if (clientMap.has(db_index)) {
        return clientMap.get(db_index);
    } else {
        let client = createClient({ url: `${config.redisConfig}/${db_index}` });
        client.on('error', (err) => log.error('Redis Client Error', err));
        client.on('connect', () => log.info('Redis Client Connected'));
        client.on('ready', () => log.info('Redis Client Ready'));
        client.on('end', () => log.warn('Redis Client End'));
        client.on('reconnecting', () => log.warn('Redis Client reconnecting'));
        await client.connect();
        clientMap.set(db_index, client);
        return client;
    }
}

//获取24-48小时内的随机失效时间
function getRandomExpireTime() {
    let time = 24 * 60 * 60 + Math.floor(Math.random() * 24 * 60 * 60);
    return time;
}

async function setAutoExpire(key, value, db_index = 0) {
    let client = await getClient(db_index);
    await client.set(key, value, {
        EX: getRandomExpireTime(),
    });
}
async function set(key, value, ExpireTime = null, db_index = 0) {
    let client = await getClient(db_index);
    await client.set(key, value, {
        EX: ExpireTime,
    });
}
async function get(key, db_index = 0) {
    let client = await getClient(db_index);
    return await client.get(key);
}
async function del(key, db_index = 0) {
    let client = await getClient(db_index);
    return await client.del(key);
}
async function setnx(key, value, ExpireTime = null, db_index = 0) {
    let client = await getClient(db_index);
    const setResult = await client.setNX(key, value);

    if (setResult && ExpireTime) {
        // 如果设置成功，则设置过期时间
        await client.expire(key, ExpireTime);
    }

    return setResult;
}
/*
rediskey 查询和存储
tablename 表名
data 查询参数
*/
async function getandset(rediskey, tablename, data, db_index = 0) {
    let redisdata = await get(rediskey, db_index);
    if (!redisdata || redisdata == {}) {
        try {
            const findonedata = await mysqlHelper.findOne(tablename, data);
            if (findonedata) {
                await setAutoExpire(rediskey, JSON.stringify(findonedata), db_index);
                redisdata = JSON.stringify(findonedata);
            }
        } catch (error) {
            return error;
        }
    }
    return JSON.parse(redisdata);
}
export default {
    setAutoExpire,
    set,
    get,
    getandset,
    getClient,
    del,
    setnx,
};
